import 'dart:async';

import 'package:casdon/app/config/env/common_config.dart';
import 'package:casdon/core/logger/log.dart';
import 'package:casdon/core/network/business_exception.dart';
import 'package:casdon/modules/me/domain/states/social_binded_list_state.dart';
import 'package:casdon/modules/me/domain/usecase/social_bind_usecase.dart';
import 'package:casdon/modules/me/domain/usecase/social_binded_list_usecase.dart';
import 'package:casdon/modules/me/domain/usecase/social_delbind_usecase.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:fluwx/fluwx.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
import 'package:uuid/uuid.dart';

class SocialAccountNotifier extends AutoDisposeNotifier<SocialBindedListState> {
  bool _bindingInFlight = false;
  bool _wechatCallbackHandled = false;
  Timer? _bindTimeoutTimer;

  Future<void> getSocialList() async {
    SocialBindedListState astate = SocialBindedListState.initial();
    try {
      final accounts = await ref
          .read(socialBindedListUsecaseProvider)
          .execute();
      if (accounts == null) return;

      for (var element in accounts) {
        if (element.source == SocialBindedListState.KAppleSource) {
          astate = astate.copyWith(
            appleAccount: element.email,
            appleAuthId: element.authId,
            appleId: element.id,
            errorMsg: null,
          );
        }
        if (element.source == SocialBindedListState.KWXSource) {
          astate = astate.copyWith(
            wxAccount: element.nickName,
            wxAuthId: element.authId,
            wxId: element.id,
            errorMsg: null,
          );
        }
      }
      state = astate;
      return;
    } on BusinessException catch (e) {
      state = state.copyWith(errorMsg: e.msg);
    } catch (e) {
      state = state.copyWith(errorMsg: e.toString());

      return;
    }
  }

  Future<void> bindSocial({required String source}) async {
    if (_bindingInFlight) {
      Log.i('绑定请求已在进行中，忽略重复点击');
      return;
    }
    _bindingInFlight = true;
    _wechatCallbackHandled = false;
    if (source == SocialBindedListState.KWXSource) {
      // 清理旧的微信绑定标识，避免使用过期 authId
      state = state.copyWith(wxAccount: null, wxAuthId: null, wxId: null);
      await _wxauth();
      _startBindTimeout();
      return;
    }

    if (source == SocialBindedListState.KAppleSource) {
      await _appleAuth();
      return;
    }
    _bindingInFlight = false;
  }

  // apple绑定
  Future<void> _appleAuth() async {
    try {
      final credential = await SignInWithApple.getAppleIDCredential(
        scopes: [
          AppleIDAuthorizationScopes.email,
          AppleIDAuthorizationScopes.fullName,
        ],
      );
      _onSignedIn(credential);
    } on SignInWithAppleAuthorizationException catch (e) {
      // 注意这里捕获的是 AuthorizationError
      if (e.code == AuthorizationErrorCode.canceled) {
        Log.i('用户取消登录');
        // state = state.copyWith(errorMsg: "用户取消登录");
      } else {
        Log.e('Apple 登录错误', e.toString(), StackTrace.current);
        state = state.copyWith(errorMsg: "授权失败");
      }
      _bindingInFlight = false;
    } catch (e) {
      Log.e('Apple 登录异常', e.toString(), StackTrace.current);
      state = state.copyWith(errorMsg: "授权失败");
      _bindingInFlight = false;
    }
  }

  Future<void> _onSignedIn(AuthorizationCredentialAppleID credential) async {
    // setSuccess("苹果授权成功");
    Log.i('---------- Apple 登录凭据 ----------');
    Log.i('Authorization Code: ${credential.authorizationCode}');

    await _bindSocial("appleid", credential.authorizationCode);
  }

  // 微信登录
  Future<void> _wxauth() async {
    try {
      _wechatCallbackHandled = false;
      Fluwx().removeSubscriber(_responseWechat);
      Fluwx().addSubscriber(_responseWechat);
      final result = await Fluwx().authBy(
        which: NormalAuth(scope: CommonConfig.WX_authScope, state: Uuid().v4()),
      );
      if (result == false) {
        state = state.copyWith(errorMsg: "微信授权失败");
        Fluwx().removeSubscriber(_responseWechat);
        _bindingInFlight = false;
        _cancelBindTimeout();
        return;
      }
    } catch (e) {
      Log.e("微信授权失败", e.toString(), StackTrace.current);
      Fluwx().removeSubscriber(_responseWechat);
      _bindingInFlight = false;
      _cancelBindTimeout();
    }
  }

  void resetBindinInFlight() {
    _bindingInFlight = false;
  }

  Future<void> _responseWechat(WeChatResponse response) async {
    try {
      if (_wechatCallbackHandled) {
        Log.i('忽略重复的微信回调');
        return;
      }
      _wechatCallbackHandled = true;
      String? authCode;
      if (response.isSuccessful == false) {
        state = state.copyWith(errorMsg: "微信授权失败");
        Log.e("微信授权失败", response, null);
        return;
      } else {
        switch (response) {
          case WeChatAuthResponse(:var code, :var state):
            authCode = code;
          default:
            Log.i("通用响应处理");
        }
        if (authCode == null) {
          return;
        }
        Log.i(
          " response = ${response.errCode} , ${response.errStr}, ${response.toString()}",
        );
        await _bindSocial("wechat_open", authCode);
      }
    } finally {
      _bindingInFlight = false;
      Fluwx().removeSubscriber(_responseWechat);
      _cancelBindTimeout();
    }
  }

  Future<void> _bindSocial(String source, String authCode) async {
    try {
      bool ret = await ref
          .read(socialBindUsecaseProvider)
          .execute(source: source, authCode: authCode);

      if (ret == true) {
        state = state.copyWith(errorMsg: null);
        getSocialList();
        return;
      }
    } on BusinessException catch (e) {
      state = state.copyWith(errorMsg: e.msg);
      return;
    } catch (e) {
      state = state.copyWith(errorMsg: e.toString());

      return;
    }
    return;
  }

  void _startBindTimeout() {
    _cancelBindTimeout();
    _bindTimeoutTimer = Timer(const Duration(seconds: 60), () {
      Log.i('绑定超时，重置状态以便重试');
      Fluwx().removeSubscriber(_responseWechat);
      _bindingInFlight = false;
      _wechatCallbackHandled = false;
    });
  }

  void _cancelBindTimeout() {
    _bindTimeoutTimer?.cancel();
    _bindTimeoutTimer = null;
  }

  Future<void> delBindSocial({required String source}) async {
    try {
      String? socialId;
      if (source == SocialBindedListState.KAppleSource) {
        socialId = state.appleId;
      }
      if (source == SocialBindedListState.KWXSource) {
        socialId = state.wxId;
      }
      if (socialId == null) return;

      bool ret = await ref.read(socialDelBindUsecaseProvider).execute(socialId);
      if (ret == true) {
        if (source == SocialBindedListState.KAppleSource) {
          state = state.copyWith(
            appleAccount: null,
            appleAuthId: null,
            appleId: null,
            errorMsg: null,
          );
          await getSocialList();
          return;
        }
        if (source == SocialBindedListState.KWXSource) {
          state = state.copyWith(
            wxAccount: null,
            wxAuthId: null,
            wxId: null,
            errorMsg: null,
          );
          await getSocialList();
          return;
        }
      }
    } on BusinessException catch (e) {
      state = state.copyWith(errorMsg: e.msg);
      return;
    } catch (e) {
      state = state.copyWith(errorMsg: e.toString());

      return;
    } finally {
      _bindingInFlight = false;
    }
  }

  @override
  SocialBindedListState build() {
    ref.onDispose(() {
      Log.i("清除：SocialAccountNotifier");
      Fluwx().removeSubscriber(_responseWechat);
    });
    return SocialBindedListState.initial();
  }
}

final socialAccountNotifierProvider =
    AutoDisposeNotifierProvider<SocialAccountNotifier, SocialBindedListState>(
      () {
        return SocialAccountNotifier();
      },
    );
